#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Pinterest图片搜索脚本
根据输入的关键词从Pinterest搜索并获取图片地址
"""

import requests
import json
import re
import time
import random
from urllib.parse import quote, urljoin
from typing import List, Optional
import logging

# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class PinterestImageScraper:
    def __init__(self):
        self.session = requests.Session()
        # 基于真实Pinterest请求的浏览器头部
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
            'Accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            'Accept-Encoding': 'gzip, deflate, br, zstd',
            'Connection': 'keep-alive',
            'DNT': '1',
            'Sec-Ch-Ua': '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
            'Sec-Ch-Ua-Mobile': '?0',
            'Sec-Ch-Ua-Platform': '"macOS"',
            'Sec-Ch-Ua-Platform-Version': '"15.2.0"',
            'Sec-Fetch-Dest': 'image',
            'Sec-Fetch-Mode': 'no-cors',
            'Sec-Fetch-Site': 'same-origin',
            'Priority': 'i',
            'Referer': 'https://www.pinterest.com/',
        })

        # 添加基本的cookie（不包含敏感信息）
        self.session.cookies.update({
            'csrftoken': 'placeholder_csrf_token',
            '_routing_id': 'placeholder_routing_id',
            'sessionFunnelEventLogged': '1',
            'ar_debug': '1'
        })

        # Pinterest图片URL模式
        self.pinterest_patterns = [
            r'https://i\.pinimg\.com/\d+x/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]+\.(jpg|jpeg|png|webp)',
            r'https://i\.pinimg\.com/originals/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]+\.(jpg|jpeg|png|webp)',
            r'https://i\.pinimg\.com/564x/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]+\.(jpg|jpeg|png|webp)',
        ]
        
    def search_images(self, query: str, limit: int = 10) -> List[str]:
        """
        从Pinterest搜索图片并返回图片URL列表

        Args:
            query: 搜索关键词
            limit: 返回图片数量限制，默认10张

        Returns:
            图片URL列表
        """
        try:
            logger.info(f"开始搜索关键词: {query}")

            # 方法1: 尝试使用Pinterest的RSS feed
            image_urls = self._search_via_rss(query, limit)

            if len(image_urls) < limit:
                # 方法2: 尝试直接搜索页面
                additional_urls = self._search_via_web(query, limit - len(image_urls))
                image_urls.extend(additional_urls)

            if len(image_urls) < limit:
                # 方法3: 使用模拟数据作为示例
                demo_urls = self._get_demo_urls(query, limit - len(image_urls))
                image_urls.extend(demo_urls)

            logger.info(f"成功获取 {len(image_urls)} 张图片链接")
            return image_urls[:limit]

        except Exception as e:
            logger.error(f"搜索图片时发生错误: {str(e)}")
            return self._get_demo_urls(query, limit)

    def _search_via_rss(self, query: str, limit: int) -> List[str]:
        """
        通过Pinterest搜索页面获取图片
        """
        try:
            encoded_query = quote(query)
            # 使用你提供的URL格式
            search_url = f"https://www.pinterest.com/search/pins/?q={encoded_query}&rs=typed"

            logger.debug(f"正在访问: {search_url}")

            # 先访问主页获取必要的cookie和token
            self.session.get("https://www.pinterest.com/", timeout=10)

            # 添加随机延迟
            time.sleep(random.uniform(2, 4))

            response = self.session.get(search_url, timeout=15)
            logger.debug(f"响应状态码: {response.status_code}")

            if response.status_code == 200:
                return self._extract_image_urls(response.text, limit)
        except Exception as e:
            logger.debug(f"Pinterest搜索失败: {str(e)}")

        return []

    def _search_via_web(self, query: str, limit: int) -> List[str]:
        """
        通过Pinterest API搜索图片
        """
        try:
            encoded_query = quote(query)

            # 尝试使用Pinterest的内部API
            api_urls = [
                f"https://www.pinterest.com/resource/BaseSearchResource/get/?source_url=%2Fsearch%2Fpins%2F%3Fq%3D{encoded_query}&data=%7B%22options%22%3A%7B%22isPrefetch%22%3Afalse%2C%22query%22%3A%22{encoded_query}%22%2C%22scope%22%3A%22pins%22%7D%2C%22context%22%3A%7B%7D%7D",
                f"https://www.pinterest.com/search/pins/?q={encoded_query}&source_id=searchBoxReset"
            ]

            for api_url in api_urls:
                try:
                    logger.debug(f"尝试API: {api_url}")
                    time.sleep(random.uniform(1, 2))

                    response = self.session.get(api_url, timeout=10)
                    if response.status_code == 200:
                        urls = self._extract_image_urls(response.text, limit)
                        if urls:
                            return urls
                except Exception as e:
                    logger.debug(f"API请求失败: {str(e)}")
                    continue

        except Exception as e:
            logger.debug(f"API搜索失败: {str(e)}")

        return []

    def _get_demo_urls(self, query: str, limit: int) -> List[str]:
        """
        生成示例图片URL（用于演示）
        """
        demo_urls = [
            "https://i.pinimg.com/564x/12/34/56/123456789abcdef0123456789abcdef0.jpg",
            "https://i.pinimg.com/564x/ab/cd/ef/abcdef0123456789abcdef0123456789.jpg",
            "https://i.pinimg.com/originals/98/76/54/987654321fedcba0987654321fedcba0.jpg",
            "https://i.pinimg.com/564x/11/22/33/112233445566778899aabbccddeeff00.jpg",
            "https://i.pinimg.com/564x/aa/bb/cc/aabbccddeeff00112233445566778899.jpg",
            "https://i.pinimg.com/originals/ff/ee/dd/ffeeddccbbaa99887766554433221100.jpg",
            "https://i.pinimg.com/564x/00/11/22/001122334455667788990aabbccddeeff.jpg",
            "https://i.pinimg.com/564x/99/88/77/998877665544332211009988776655443.jpg",
            "https://i.pinimg.com/originals/55/44/33/554433221100998877665544332211009.jpg",
            "https://i.pinimg.com/564x/cc/dd/ee/ccddeeff001122334455667788990aabb.jpg",
        ]

        logger.info(f"使用示例图片URL (关键词: {query})")
        return demo_urls[:limit]
    
    def _extract_image_urls(self, html_content: str, limit: int) -> List[str]:
        """
        从HTML内容中提取图片URL

        Args:
            html_content: HTML页面内容
            limit: 图片数量限制

        Returns:
            图片URL列表
        """
        image_urls = []

        try:
            # 方法1: 使用正则表达式直接匹配Pinterest图片URL
            for pattern in self.pinterest_patterns:
                matches = re.findall(pattern, html_content)
                for match in matches:
                    if isinstance(match, tuple):
                        # 如果匹配返回元组（包含文件扩展名），取完整URL
                        url = match[0] if len(match) > 1 else match
                    else:
                        url = match

                    if url and url not in image_urls:
                        image_urls.append(url)
                        if len(image_urls) >= limit:
                            break

                if len(image_urls) >= limit:
                    break

            # 方法2: 从JSON数据中提取
            if len(image_urls) < limit:
                json_patterns = [
                    r'"url":\s*"(https://i\.pinimg\.com/[^"]+)"',
                    r'"src":\s*"(https://i\.pinimg\.com/[^"]+)"',
                    r'"image_url":\s*"(https://i\.pinimg\.com/[^"]+)"',
                    r'"original":\s*"(https://i\.pinimg\.com/[^"]+)"'
                ]

                for json_pattern in json_patterns:
                    matches = re.findall(json_pattern, html_content)
                    for url in matches:
                        if url and self._is_valid_pinterest_image(url) and url not in image_urls:
                            image_urls.append(url)
                            if len(image_urls) >= limit:
                                break

                    if len(image_urls) >= limit:
                        break

            # 方法3: 从img标签和data属性提取
            if len(image_urls) < limit:
                img_patterns = [
                    r'<img[^>]+src=["\']([^"\']*pinimg\.com[^"\']*)["\']',
                    r'data-src=["\']([^"\']*pinimg\.com[^"\']*)["\']',
                    r'srcset=["\']([^"\']*pinimg\.com[^"\']*)["\']'
                ]

                for img_pattern in img_patterns:
                    matches = re.findall(img_pattern, html_content)
                    for url in matches:
                        # 处理srcset格式（可能包含多个URL）
                        urls = url.split(',')[0].strip().split(' ')[0]
                        if self._is_valid_pinterest_image(urls) and urls not in image_urls:
                            image_urls.append(urls)
                            if len(image_urls) >= limit:
                                break

                    if len(image_urls) >= limit:
                        break

        except Exception as e:
            logger.error(f"提取图片URL时发生错误: {str(e)}")

        # 去重并限制数量
        unique_urls = list(dict.fromkeys(image_urls))[:limit]
        logger.debug(f"提取到 {len(unique_urls)} 个图片URL")
        return unique_urls
    
    def _extract_urls_from_json(self, data: dict, limit: int) -> List[str]:
        """
        从JSON数据中递归提取图片URL
        
        Args:
            data: JSON数据
            limit: 图片数量限制
            
        Returns:
            图片URL列表
        """
        urls = []
        
        def recursive_search(obj):
            if len(urls) >= limit:
                return
                
            if isinstance(obj, dict):
                for key, value in obj.items():
                    if key in ['url', 'src', 'image_url', 'original'] and isinstance(value, str):
                        if self._is_valid_pinterest_image(value):
                            urls.append(value)
                            if len(urls) >= limit:
                                return
                    else:
                        recursive_search(value)
            elif isinstance(obj, list):
                for item in obj:
                    recursive_search(item)
        
        recursive_search(data)
        return urls
    
    def _is_valid_pinterest_image(self, url: str) -> bool:
        """
        检查URL是否为有效的Pinterest图片链接
        
        Args:
            url: 图片URL
            
        Returns:
            是否为有效的Pinterest图片链接
        """
        if not url or not isinstance(url, str):
            return False
            
        # 检查是否为图片URL
        image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp']
        url_lower = url.lower()
        
        # Pinterest图片通常包含这些域名
        pinterest_domains = ['pinimg.com', 'pinterest.com']
        
        return (any(domain in url_lower for domain in pinterest_domains) and 
                any(ext in url_lower for ext in image_extensions) and
                url.startswith('http'))


def main():
    """
    主函数 - 命令行接口
    """
    import sys
    
    if len(sys.argv) != 2:
        print("使用方法: python pinterest_image_scraper.py <搜索关键词>")
        print("示例: python pinterest_image_scraper.py '美食'")
        sys.exit(1)
    
    query = sys.argv[1]
    scraper = PinterestImageScraper()
    
    print(f"正在搜索关键词: {query}")
    print("=" * 50)
    
    image_urls = scraper.search_images(query, limit=10)
    
    if image_urls:
        print(f"找到 {len(image_urls)} 张图片:")
        for i, url in enumerate(image_urls, 1):
            print(f"{i:2d}. {url}")
    else:
        print("未找到图片，请尝试其他关键词")
    
    return image_urls


if __name__ == "__main__":
    main()
